package com.fourpigeon.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.fourpigeon.dao.*;
import com.fourpigeon.domain.*;
import com.fourpigeon.service.BlogPublishService;
import com.fourpigeon.utils.IdGenerator;
import com.fourpigeon.utils.UserHolder;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Random;
import java.util.concurrent.TimeUnit;

import static com.fourpigeon.utils.RedisConstants.*;
import static com.fourpigeon.utils.RedisConstants.COMMENT_CREATE_STRING_TTL;

@Service("blogPublishService")
public class BlogPublishServiceImpl extends BlogServiceImpl implements BlogPublishService {
    @Autowired
    private BlogDailyDao blogDailyDao;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private UserDao userDao;
    @Autowired
    private BlogDealDao blogDealDao;
    @Autowired
    private BlogPracticeDao blogPracticeDao;
    @Autowired
    private BlogAgreeDao blogAgreeDao;
    @Autowired
    private IdGenerator idGenerator;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private BlogCommentDao blogCommentDao;

    /**
     * 发布日常贴
     * @param blogDailyDTO 前端数据
     * @return 结果信息
     */
    @Override
    public Result publishDaily(BlogDailyDTO blogDailyDTO,Short blogType) {
        return this.publish(blogDailyDTO, BlogDaily.class,new short[]{blogType});
    }

    /**
     * 发布交易贴
     * @param blogDealDTO 前端数据
     * @return 结果信息
     */
    @Override
    public Result publishDeal(BlogDealDTO blogDealDTO) {
        return this.publish(blogDealDTO,BlogDeal.class);
    }

    /**
     * 发布约球贴
     * @param blogAgreeDTO 前端数据
     * @param blogType 博客类型
     * @return 结果信息
     */
    @Override
    public Result publishAgreement(BlogAgreeDTO blogAgreeDTO, Short blogType) { return this.publish(blogAgreeDTO,BlogAgree.class,blogType);}

    /**
     * 发布约球贴(过时方法)
     * @param blogAgreeDTO 前端数据
     * @param blogType 博客类型
     * @return 结果信息
     */
//    @Override
    @Deprecated
    public Result publishAgreement1(BlogAgreeDTO blogAgreeDTO, Short blogType) {
        if (!agreeSaveMap.containsKey(blogType)) {
            return Result.fail("类型错误!请联系工作人员!");
        }
        Long userId = UserHolder.getUser().getId();
        //加入分布式锁
        RLock lock = redissonClient.getLock(BLOG_PUBLISH_LOCK + userId);
        //尝试获取锁
        boolean isSuccess = lock.tryLock();
        if (!isSuccess) {
            return Result.fail("发帖太频繁了哦~请稍后再试!");
        }
        User user = userDao.getById(userId);
        String ttl = userId.toString();
        //检验Redis的key是否过期
        if (stringRedisTemplate.opsForValue().get(BLOG_CREATE_STRING_TTL+ttl) != null) {
            return Result.fail("发帖太频繁了哦~请稍后再试!");
        }
        //创建BlogAgree对象
        BlogAgree blogAgree = BeanUtil.copyProperties(blogAgreeDTO, BlogAgree.class);
        blogAgree.setUserId(userId);
        //使用id生成器生成博客id
        blogAgree.set(idGenerator.nextBlogId("blog"),user);
        //加入MySQL数据库
        agreeSaveMap.get(blogType).apply(blogAgree);
        //发帖延迟
        stringRedisTemplate.opsForValue().set(BLOG_CREATE_STRING_TTL+ttl,ttl,3L,TimeUnit.SECONDS);
        //Redis创建球局预约剩余人数信息
//        stringRedisTemplate.opsForValue().set("agree:remain:"+blogAgree.getId(),Integer.toString(blogAgree.getPeople() - 1));
        //释放锁
        lock.unlock();
        return Result.ok("发布成功");
    }

    /**
     * 发布教练陪练贴
     * @param blogPracticeDTO 前端数据
     * @return 结果信息
     */
    @Override
    public Result publishPractice(BlogPracticeDTO blogPracticeDTO) {
        return publish(blogPracticeDTO,BlogPractice.class);
    }

    /**
     * 发表评论
     * @param blogId 博客id
     * @return 结果信息
     */
    @Override
    public Result comment(BlogCommentDTO blogCommentDTO, Long blogId) {
        //TODO 检验用户id
        Long userId = UserHolder.getUser().getId();
//        Integer userId = 1;
        User user = userDao.getById(userId);
        String ttl = userId.toString();
        //查询Redis的TTL
        if(stringRedisTemplate.opsForValue().get(COMMENT_CREATE_STRING_TTL+ttl)!=null){
            return Result.fail("回复太快了哦~请稍后再试!");
        }
        //计算评论在博客种的楼层号
        //查询Redis记录的楼层号
        String stageStr = stringRedisTemplate.opsForValue().get(BLOG_COMMENT_NUM + blogId);
        int stage = Integer.parseInt(stageStr)+1;
        //生成BlogComment对象
        BlogComment blogComment = BeanUtil.copyProperties(blogCommentDTO, BlogComment.class);
        blogComment.set(idGenerator.nextCommentId(),blogId,stage,user);
        //保存数据库
        blogCommentDao.save(blogComment);
        //更新博客数据库评论数量(+1)
        blogDailyDao.updateCommentNum(blogId);
        //更新Redis评论数量(+1)
        stringRedisTemplate.opsForValue().increment(BLOG_COMMENT_NUM+blogId);
        //创建RedisTTL,3s
        stringRedisTemplate.opsForValue().set(COMMENT_CREATE_STRING_TTL+ttl,ttl,3,TimeUnit.SECONDS);
        //返回结果
        return Result.ok("评论成功!");
    }
}
